#include <iostream>
#include <fstream>
#include <string>
#include <cstring>
#include "bundle.h"

//压缩
// void Usage()
// {
//     std::cout<<"Usage:"<<std::endl;
//     std::cout<<"\texe {FILE NAME} {COMPRESS TYPE}"<<std::endl;
//     std::cout<<"\tcompress type:\n"<<std::endl;
//     std::cout<<"\t\tRAW, SHOCO, LZ4F, MINIZ, LZIP, LZMA20, ZPAQ, LZ4,"<<std::endl;
//     std::cout<<"\t\tBROTLI9, ZSTD, LZMA25, BSC, BROTLI11, SHRINKER, CSC20,ZSTDF, "<<std::endl;
//     std::cout<<"\t\tBCM, ZLING, MCM, TANGELO, ZMOLLY, CRUSH, LZJB, BZIP2 \n"<<std::endl;
// }
// int main(int argc,char** argv)
// {
//     if(argc < 3)
//     {
//         Usage();
//         return 1;
//     }

//     //设置压缩类型
//     std::string types(argv[2]);
//     std::string s[24] = {"RAW","SHOCO","LZ4F","MINIZ","LZIP","LZMA20","ZPAQ","LZ4","BROTLI9","ZSTD","LZMA25","BSC","BROTLI11","SHRINKER",\
//     "CSC20","ZSTDF","BCM","ZLING","MCM","TANGELO","ZMOLLY","CRUSH","LZJB","BZIP2"};
//     int type = -1;
//     for(int i = 0;i<24;++i)
//     {
//         if(s[i] == types)
//         {
//             type = i;
//             break;
//         }
//     }

//     if(type == -1)
//     {
//         std::cout<<"compress type Incorrect!"<<std::endl;
//         std::cout<<"\treference compress type:\n"<<std::endl;
//         std::cout<<"\t\tRAW, SHOCO, LZ4F, MINIZ, LZIP, LZMA20, ZPAQ, LZ4,"<<std::endl;
//         std::cout<<"\t\tBROTLI9, ZSTD, LZMA25, BSC, BROTLI11, SHRINKER, CSC20,ZSTDF, "<<std::endl;
//         std::cout<<"\t\tBCM, ZLING, MCM, TANGELO, ZMOLLY, CRUSH, LZJB, BZIP2 \n"<<std::endl;
//         return 2;
//     }

//     //读取文件名
//     std::string ism(argv[1]);

//     //读取文件 写入内存
//     std::ifstream ifs;
//     ifs.open(ism,std::ios::binary);
//     if(ifs.is_open() == false)
//     {
//         std::cout<<"{"<<ism<<"}"<<" the file does not exist!"<<std::endl;
//         return 3;
//     }
//     ifs.seekg(0,std::ios::end); //文件流指针到文件末尾
//     size_t fsize = ifs.tellg(); //获取文件从开始位置到当前位置的偏移量(相当于获取文件字节数)
//     ifs.seekg(0,std::ios::beg); //文件流指针到文件开始

//     std::string content; //读取文件内容
//     content.resize(fsize);
//     ifs.read(&content[0],fsize);

//     //写入文件名
//     std::string osm(ism);
//     osm += ".";
//     osm += argv[2];

//     std::string zcontent = bundle::pack(type,content);

//     std::ofstream ofs;
//     ofs.open(osm,std::ios::binary);
//     ofs.write(&zcontent[0],zcontent.size());

//     ifs.close();
//     ofs.close();
//     std::cout<<"pack success! pack size: "<<zcontent.size()<<" Byte"<<std::endl;
//     return 0;
// }


//解压
void Usage()
{
    std::cout<<"Usage:"<<std::endl;
    std::cout<<"\texe {FILE NAME}"<<std::endl;
}
int main(int argc,char** argv)
{
    if(argc < 2)
    {
        Usage();
        return 1;
    }

    //读取文件名 检查文件合法性
    std::string ism(argv[1]);
    auto pos = ism.rfind(".");
    std::string types = ism.substr(pos+1);
    std::string s[24] = {"RAW","SHOCO","LZ4F","MINIZ","LZIP","LZMA20","ZPAQ","LZ4","BROTLI9","ZSTD","LZMA25","BSC","BROTLI11","SHRINKER",\
    "CSC20","ZSTDF","BCM","ZLING","MCM","TANGELO","ZMOLLY","CRUSH","LZJB","BZIP2"};
    int type = -1;
    for(int i = 1;pos < std::string::npos && i<24;++i)
    {
        if(s[i] == types)
        {
            type = i;
            break;
        }
    }
    std::cout<<type<<std::endl;
    if(pos == std::string::npos || type == -1)
    {
        std::cout<<"The document is not legitimate!"<<std::endl;
        return 2;
    }

    //读取文件 写入内存
    std::ifstream ifs;
    ifs.open(ism,std::ios::binary);
    if(ifs.is_open() == false)
    {
        std::cout<<"{"<<ism<<"}"<<" the file does not exist!"<<std::endl;
        return 3;
    }
    ifs.seekg(0,std::ios::end); //文件流指针到文件末尾
    size_t fsize = ifs.tellg(); //获取文件从开始位置到当前位置的偏移量(相当于获取文件字节数)
    ifs.seekg(0,std::ios::beg); //文件流指针到文件开始

    std::string content; //读取文件内容
    content.resize(fsize);
    ifs.read(&content[0],fsize);

    //写入文件名
    std::string osm(ism.substr(0,pos));
    osm += ".copy";

    std::string zcontent = bundle::unpack(content);

    std::ofstream ofs;
    ofs.open(osm,std::ios::binary);
    ofs.write(&zcontent[0],zcontent.size());

    std::cout<<"unpack success! unpack size:"<< zcontent.size() <<" Byte"<<std::endl;

    ifs.close();
    ofs.close();
    return 0;
}